package com.sch.www.sys.controller;

import com.baidu.unbiz.fluentvalidator.ComplexResult;
import com.baidu.unbiz.fluentvalidator.FluentValidator;
import com.baidu.unbiz.fluentvalidator.ResultCollectors;
import com.sch.www.common.base.BaseController;
import com.sch.www.common.base.CustomPage;
import com.sch.www.common.base.ResultBean;
import com.sch.www.common.validator.IdCardFluentValidator;
import com.sch.www.common.validator.NotBlankFluentValidator;
import com.sch.www.ele.entity.CareUser;
import com.sch.www.ele.feign.CareUserApi;
import com.sch.www.sys.dto.UserInfo;
import com.sch.www.sys.orm.entity.manual.Account;
import com.sch.www.sys.orm.entity.manual.Role;
import com.sch.www.sys.services.AccountServices;
import com.sch.www.sys.services.ResourceServices;
import com.sch.www.sys.services.RoleServices;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.Principal;
import java.util.List;
import java.util.stream.Collectors;

@RequestMapping("/v1/account")
@RestController
public class AccountController extends BaseController {

    @Autowired
    AccountServices accountServices;
    @Autowired
    RoleServices roleServices;
    @Autowired
    ResourceServices resourceServices;
    @Autowired
    CareUserApi careUserApi;


    @RequestMapping("/username/{username}")
    public ResultBean<Account> loginAccount(@PathVariable String username) {
        ResultBean<Account> resultBean = ResultBean.newInstance();
        if (StringUtils.isBlank(username)) {
            resultBean.setError().setMsg("username不能为空。");
        } else {
            Account account = accountServices.selectByUsername(username);
            if (account != null) {
                account.setRoleList(roleServices.selectByAccountId(account.getId()));
                account.setResourceList(resourceServices.selectByAccountId(account.getId()));
            }
            resultBean.setSuccess().setData(account);
        }
        return resultBean;
    }


    @RequestMapping(value = "/userInfo")
    public ResultBean<UserInfo> userInfo(Principal principal,OAuth2Authentication authentication) {

        Account account = accountServices.selectByUsername(authentication.getName());
        List<Role> roleList = roleServices.selectByAccountId(account.getId());
        CareUser careUser = careUserApi.getByAccountId(account.getId()).getData();


        UserInfo userInfo = new UserInfo();
        userInfo.setAccount_id(account.getId());
        userInfo.setUsername(account.getUsername());

        userInfo.setRoles(roleList.stream().map(item -> item.getName()).collect(Collectors.toList()));
        userInfo.setAuthorities(authentication.getAuthorities().stream().map(item -> item.getAuthority()).collect(Collectors.toList()));
        userInfo.setUser_id(careUser.getId());
        userInfo.setName(careUser.getName());
        userInfo.setIdCard(careUser.getIdCard());
        userInfo.setPhoneNumber(careUser.getPhoneNumber());

        ResultBean<UserInfo> resultBean = ResultBean.newInstance();
        return resultBean.setSuccess().setData(userInfo);
    }


    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logoutPage(HttpServletRequest request, HttpServletResponse response) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null) {
            new SecurityContextLogoutHandler().logout(request, response, auth);
        }
        return "redirect:/login?logout";
    }

    @RequestMapping(value = "/list")
    private ResultBean<CustomPage<Account>> list(
            String username,
            String name,
            String idCard,
            Byte active,
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize) {

        ResultBean<CustomPage<Account>> resultBean = ResultBean.newInstance();
        CustomPage<Account> page = accountServices.list(username, name, idCard, active, pageNum, pageSize);
        resultBean.setSuccess().setData(page);
        return resultBean;
    }


    @PostMapping("/add")
    public ResultBean<Account> addAccount(@RequestBody Account account) {
        ResultBean<Account> resultBean = ResultBean.newInstance();
        ComplexResult complexResult = FluentValidator.checkAll().failOver()
                .on(account.getUsername(), new NotBlankFluentValidator("username"))
                .on(account.getPassword(), new NotBlankFluentValidator("name"))
                .on(account.getIdCard(), new IdCardFluentValidator("idCard"))
                .doValidate()
                .result(ResultCollectors.toComplex());
        if (!complexResult.isSuccess()) {
            return resultBean.setError().appendMsg(complexResult);
        }
        accountServices.insertSelective(account);
        return resultBean;
    }

    @PostMapping("/modify")
    public ResultBean<Account> modifyAccount(@RequestBody Account account) {
        ResultBean<Account> resultBean = ResultBean.newInstance();
        ComplexResult complexResult = FluentValidator.checkAll().failOver()
                .on(account.getId(), new NotBlankFluentValidator("id"))
                .doValidate()
                .result(ResultCollectors.toComplex());
        if (!complexResult.isSuccess()) {
            return resultBean.setError().appendMsg(complexResult);
        }
        accountServices.updateByIdSelective(account);
        return resultBean;
    }

    @DeleteMapping("/remove/{id}")
    public ResultBean<Account> removeAccount(@PathVariable String id) {
        ResultBean<Account> resultBean = ResultBean.newInstance();
        if (StringUtils.isBlank(id)) {
            resultBean.setError().setMsg("id不能为空。");
        } else {
            int result = accountServices.deleteById(id);
            if (result == 0) {
                resultBean.setError().setMsg("id不存在为空。");
            }
        }
        return resultBean;
    }
}


//    @Autowired
//    private TokenStore tokenStore;
//
//    /**
//     * 移除 token
//     *
//     * @param value
//     * @return
//     */
//
////    @PreAuthorize("hasRole('Admin') and #oauth2.hasScope('cat') ")
//    @PreAuthorize("login")
//    @RequestMapping(value = "/oauth/removeToken")
//    @ResponseBody
//    public ResultBean removeToken(Principal principal) {
//
//
//        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
//        if (auth != null){
//            new SecurityContextLogoutHandler().logout(request, response, auth);
//        }
//        return "redirect:/login?logout";
//
//        ResultBean resultBean = new ResultBean();
//
//        if (principal instanceof OAuth2Authentication) {
//
//            OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) principal;
//            Object details = oAuth2Authentication.getDetails();
//            if (details instanceof OAuth2AuthenticationDetails) {
//                String tokenValue = ((OAuth2AuthenticationDetails) details).getTokenValue();
//                OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(tokenValue);
//                if (oAuth2AccessToken != null) {
//                    tokenStore.removeAccessToken(oAuth2AccessToken);
//                    return resultBean.setSuccess();
//                }
//
//            }
//
//            return resultBean.setError().setData("")
//        }
//
//
//        OAuth2Authentication
//
//        OAuth2AccessToken token = tokenStore.readAccessToken(null);
//        if (token == null) {
//            throw new InvalidTokenException("Token was not recognised");
//        } else {
//            tokenStore.removeAccessToken(token);
//            Map<String, Object> result = new HashMap<>();
//            result.put("result", "success");
//            return result;
//        }
//
//    }